﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Collections;
using System.Collections.Generic;
using DotNetNuke.Common.Utilities;

using DotNetNuke.Entities.Modules;
using Satrabel.HttpModules.Provider;
using DotNetNuke.Framework.Providers;
using Ventrian.NewsArticles;
using DotNetNuke.Entities.Portals;
using Ventrian.NewsArticles.Components.Types;

namespace Satrabel.OpenUrlRewriter.NewsArticles
{
    public class NewsArticlesUrlRuleProvider : UrlRuleProvider
    {

        private const string ProviderType = "urlRule";
        private const string ProviderName = "newsArticlesUrlRuleProvider";

        private readonly ProviderConfiguration _providerConfiguration = ProviderConfiguration.GetProviderConfiguration(ProviderType);
        private readonly bool includePageName = true;

        public NewsArticlesUrlRuleProvider() {
            var objProvider = (DotNetNuke.Framework.Providers.Provider)_providerConfiguration.Providers[ProviderName];
            if (!String.IsNullOrEmpty(objProvider.Attributes["includePageName"]))
            {
                includePageName = bool.Parse(objProvider.Attributes["includePageName"]);
            }
            //CacheKeys = new string[] { "NewsArticles-ProperyValues-All" };
        }

        public override List<UrlRule> GetRules(int PortalId)
        {
            List<UrlRule> Rules = new List<UrlRule>();
            ArticleController ac = new ArticleController();
            CategoryController cc = new CategoryController();            
            ModuleController mc = new ModuleController();            
            PortalSettings ps = new PortalSettings(PortalId);           
            ArrayList modules = mc.GetModulesByDefinition(PortalId, "DnnForge - NewsArticles");
            //foreach (ModuleInfo module in modules.OfType<ModuleInfo>().GroupBy(m => m.ModuleID).Select(g => g.First())){                
            foreach (ModuleInfo module in modules.OfType<ModuleInfo>())
            {
                ArticleSettings settings = new ArticleSettings(mc.GetModuleSettings(module.ModuleID), ps, module);

                if (settings.UrlModeType == UrlModeType.Classic)
                {

                    var articles = ac.GetArticleList(module.ModuleID);
                    foreach (ArticleInfo article in articles)
                    {
                        
                        var rule = new UrlRule
                        {
                            CultureCode = module.CultureCode,
                            TabId = module.TabID,
                            RuleType = UrlRuleType.Module,
                            Parameters = "articleType=ArticleView&" + "articleId=" + article.ArticleID.ToString(),
                            Action = UrlRuleAction.Rewrite,
                            Url = CleanupUrl(article.Title),
                            RemoveTab = !includePageName
                        };
                        Rules.Add(rule);
                        var articleCategories = ac.GetArticleCategories(article.ArticleID);
                        foreach (CategoryInfo cat in articleCategories)
                        {
                            var ruleCat = new UrlRule
                            {
                                CultureCode = module.CultureCode,
                                TabId = module.TabID,
                                RuleType = UrlRuleType.Module,
                                Parameters = "articleType=ArticleView&" + "articleId=" + article.ArticleID.ToString() + "&categoryId=" + cat.CategoryID.ToString(),
                                Action = UrlRuleAction.Rewrite,
                                Url = CleanupUrl(cat.Name) + "/" + CleanupUrl(article.Title),
                                RemoveTab = !includePageName
                            };
                            var parentCat = cc.GetCategory(cat.CategoryID, module.ModuleID);
                            while (parentCat.ParentID != Null.NullInteger)
                            {
                                parentCat = cc.GetCategory(parentCat.ParentID, module.ModuleID);
                                ruleCat.Url = CleanupUrl(parentCat.Name) + "/" + ruleCat.Url;
                            }


                            Rules.Add(ruleCat);
                        }                        
                    }
                    var categories = cc.GetCategoriesAll(module.ModuleID);
                    foreach (CategoryInfo cat in categories)
                    {
                        var rule = new UrlRule
                        {
                            CultureCode = module.CultureCode,
                            TabId = module.TabID,
                            RuleType = UrlRuleType.Module,
                            Parameters = "articleType=CategoryView&" + "categoryId=" + cat.CategoryID.ToString(),
                            Action = UrlRuleAction.Rewrite,
                            Url = CleanupUrl(cat.Name),
                            RemoveTab = !includePageName
                        };
                        var parentCat = cat;
                        while (parentCat.ParentID != Null.NullInteger)
                        {
                            parentCat = cc.GetCategory(parentCat.ParentID, module.ModuleID);
                            rule.Url = CleanupUrl(parentCat.Name) + "/" + rule.Url;
                        }
                        Rules.Add(rule);
                       
                    }

                    var archives = ac.GetNewsArchive(module.ModuleID, null, null, Null.NullInteger, GroupByType.Month, false);
                    foreach (var arch in archives) {
                        var rule = new UrlRule
                        {
                            CultureCode = module.CultureCode,
                            TabId = module.TabID,
                            RuleType = UrlRuleType.Module,
                            Parameters = "articleType=ArchiveView" + "&year=" + arch.Year.ToString(),
                            Action = UrlRuleAction.Rewrite,
                            Url = arch.Year.ToString() ,
                            RemoveTab = !includePageName
                        };
                        Rules.Add(rule);
                    }

                    archives = ac.GetNewsArchive(module.ModuleID, null, null, Null.NullInteger, GroupByType.Month, false);
                    foreach (var arch in archives)
                    {
                        var rule = new UrlRule
                        {
                            CultureCode = module.CultureCode,
                            TabId = module.TabID,
                            RuleType = UrlRuleType.Module,
                            Parameters = "articleType=ArchiveView" + "&month=" + arch.Month.ToString() + "&year=" + arch.Year.ToString(),
                            Action = UrlRuleAction.Rewrite,
                            Url = arch.Year.ToString() + "/" + arch.Month.ToString(),
                            RemoveTab = !includePageName
                        };
                        Rules.Add(rule);
                    }

                    AuthorController auc = new AuthorController();
                    var authors = auc.GetAuthorList(module.ModuleID);
                    foreach (var author in authors)
                    {
                        var rule = new UrlRule
                        {
                            CultureCode = module.CultureCode,
                            TabId = module.TabID,
                            RuleType = UrlRuleType.Module,
                            Parameters = "articleType=AuthorView" + "&authorID=" + author.UserID.ToString(),
                            Action = UrlRuleAction.Rewrite,
                            Url = CleanupUrl(author.DisplayName),
                            RemoveTab = !includePageName
                        };
                        Rules.Add(rule);
                    }



                }
            }           
            return Rules;
        }

    }
}